#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QDateTime>
#include <QMainWindow>
#include <QTimer>
#include <QDir>
#include "seat.h"
#include "controlcommand.h"
#include "defectinfo.h"
#include "detectionresult.h"
#include "savelog.h"
#include "seatdetectionparameter.h"
#include "viewwidget.h"
#include "TCPRecognizeClient.h"
#include "detectiondialog.h"
#include "seatparameterdialog.h"
#include "sqlitedatabasedao.h"
#include "plccontrolcmd.h"
#include "defectdao.h"
#include "detectiondao.h"
#include "seatdao.h"
#include "seatmatcher.h"
#include "GxIAPI.h"
#include "camera.h"
#include "GXBitmap.h"
#include "scancamerathread.h"
#include "TCPPLCClient.h"
#include "description/description.h"
#include "historyinformation.h"

//#define USE_LOGGING // 使用使用日志文件输出

#define SHOW_10X_IMAGE

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QTimer                  *m_pTimer;
    TCPPLCClient            *m_pTcpPLCClient;
    TCPRecognizeClient      *m_pTcpRecognizeClient;
    SeatParameterDialog     *m_pSeatParameterDialog;
    DetectionDialog         *m_pDetectionDialog;

    // 程序参数
    SeatDetectionParameter  seatDetectionParameter;
    // 发送图像处理器的指令
    ControlCommand          controlCommand;
    // 接收图像处理器的结果
    DetectionResult         detectionResult;
    // 接收PLC指令
    PLCControlCmd           plccontrolcmd;

    //当前座椅信息(保存了托盘、座椅和方向信息)
    Seat                    currentSeat;
    int                     m_nLastSeatId;
    //前一个座椅信息(保存了托盘、座椅和方向信息)
    Seat previousSeat;
    // 座椅匹配器
    SeatMatcher             seatMatcher;
    //
    SeatDao                 *pSeatDao;
    DetectionDao            *pDetectionDao;
    DefectDao               *pDefectDao;

    SQliteDatabaseDAO       sqlitedatabasedao;

private:
    // 统计信息，在状态栏里显示
    QLabel                  *infoLabel;
    int                     m_nTrayCount;
    int                     m_nSeatCount;
    int                     m_nDetectionCount;
    int                     m_nDefectSeatCount;
    int                     m_nDefectCount;

    /////////////////////////////////////////////////////////
    /// \brief 相机使用的变量
    /////
private:
    QList<QWidget*>             m_pWidgetVideos;
    QList<Camera*>              m_pCameras;
    bool                        m_bHasSomeClosed;
    //QList<CGXBitmap*>           m_pBitmaps;
    GX_STATUS                   emStatus;

private:
    ScanCameraThread*           m_pScanCameraThread;
    void ScanCameras();

private:
    // 运行流程
    //Description                 m_description;

    DescriptionThread           *m_descriptionThread;

public:
    static MainWindow*          instance();

private:
    static MainWindow*          _instance;

private:
    QList<DetectionResult*>      m_DetectionResults;
    QList<DetectionResult*>      m_DetectionResultsForQuery;

    QList<HISTORYINFORMATION*>   m_HistoryInformations;

    void ClearDetetionResults(){
        foreach (DetectionResult* pDR, m_DetectionResults) {
            delete pDR;
        }

        m_DetectionResults.clear();
    }

    void ComputeHistoryInformation(HISTORYINFORMATION& hi){
        hi.defectCount = 0;
        foreach (DetectionResult* pDR, m_DetectionResults) {
            hi.defectCount += pDR->GetResult().size();
            hi.seatNumber = pDR->GetInfo().GetSeatNumber();
        }

        QDateTime dateTime = QDateTime::currentDateTime();
        hi.detectionDate = dateTime.toString("yyyy-MM-dd HH:mm:ss");
    }

private:
    // 上电自检程序
    void SelfTest();

    void InitCentralWidget();
    void InitButtonWidget();
    void InitLogoWidget();
    void InitMainCameraWidget();
    void InitMainExportWidget();
    void InitControlWidget();
    void InitCompositeWidget();
    void InitSubCameraWidget();
    void InitTimerWidget();

    void InitTCPRecognizeClient();
    void InitTCPPLCClient();

    void InitLog();
    void UninitLog();

    void InitParameterFromXMLFile(QString xmlFilePath);

    void InitDatabase();

    void InitStatuBar();

    void InitDescription();

    ///////////////////////////////////////////////////////
    // 软触发，采集一张图片，传递对应相机的编号
    void SnapCameraImage(int cameraNum);

    void DisplaySystemTime();

public:
    void QueryRecentSeat(int howMuch = 5);

public slots:
    // 测试，按钮触发抓拍图像
    void SnapImageFunction(QString deviceIP,QString image);
    // 接收到从Description转发的抓拍图像或识别图像
    void ProcessImageFromDescription(QVariant variant);

private slots:
    void timerTimeOut();
    // 开始在线检测
    void ButtonRunFunction();
    // 开始在线测试
    void ButtonTestFunction();
    // 配置参数对话框
    void ButtonParameterConfigFunction();
    // 保存当前图像
    void ButtonSaveFunction();
    // 计算当前选中的一张图像的结果
    void ButtonComputeCurrentFunction();
    // 计算所有图像的结果
    void ButtonComputeAllFunction();

    // 视频
    void ButtonVideoFunction();

    void on_pushButtonHelp_clicked();

    void on_pushButtonDataQuery_clicked();

    void on_pushButtonExportSetting_clicked();

    void on_pushButtonResetStatistics_clicked();

    void on_pushButtonDetectionDescription_clicked();

    void on_pushButtonIndexAnalysis_clicked();

    void on_buttonSnap_clicked();

    void on_buttonVideo_clicked();

signals:
    // 向检测对话框发送日志信息
    void SendLogMessageToTextBrowser(QString message);
    // 向检测对话框发送清除上一个座椅的信息
    void ClearDetectionDialogImage();
    // 向检测对话框发送一个检测结果
    void SendHistoryInformation(QList<HISTORYINFORMATION*> his);
    // 向检测对话框发送开始检测信息
    //void SendPLCControlMessage(QString seatNumber);

private:
    //WaitForTheLoading*     m_pLoadDialog;

signals:
    void SendInformation(QString message);

private:
    void UpdateStatusBarInfo();
    ///////////////////////////////////////////////////////////////
    /// \brief 相机相关的函数
    ///
private:
    void InitCameraLib();
    GX_STATUS InitDevice();
    void OnClose();

protected:
    virtual void resizeEvent(QResizeEvent *event) override;

    void ProcessOneComputeResultFunctionFromRecognizeService(QString resultJson);

public slots:
    // 从Recognize服务器收到一条计算结果
    void ReceviceComputeResultFunctionFromRecognizeService(QString resultJson);
    // 从PLC控制处理服务器接收新座椅，驱动一个座椅后续操作(s)
    void ReceiveControlCmdFunctionFromPLCService(QString trayNumber,QString seatNumber,QString direction);
    // 接收从DetectionDialog用户控制信号
    void RecviceControlCmdFunctionFromDialog(QString content);
    // 接收从DetectionDialog查询座椅信号
    void RecviceQuerySeatFromDialog(QString seatNumber);
};
#endif // MAINWINDOW_H
